package container.impl;

import connector.Connector;
import container.Server;
import container.Service;
import lifecycle.LifecycleBase;

import java.util.concurrent.*;

/**
 * @ClassName : StandServer
 * @Description : 1
 * @Author : zhangxiaohai
 * @Date: 2021-06-24 17:27
 */
public class StandServer extends LifecycleBase implements Server {
    private Service[] services = new Service[0];
    private Connector[] connectors = new Connector[0];

    private Executor executor;

    @Override
    protected void initInternal() throws Exception {
        // 初始化 Service
        for (Service service : services) {
            service.init();
        }
        // 初始化 Connector
        for (Connector connector : connectors) {
            connector.init();
        }

        // 定义 Minicat 线程池
        int corePoolSize = 10; // 核心线程池大小
        int maximumPoolSize = 50; // 线程池最大大小
        long keepAliveTime = 100L; // 空闲存活时间
        TimeUnit unit = TimeUnit.SECONDS; // 存活时间单位
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(50); // 队列
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 创建线程工厂
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); // 拒绝策略

        this.executor = new ThreadPoolExecutor(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler);
    }

    @Override
    protected void startInternal() {
        for (Service service : services) {
            service.start();
        }
        for (Connector connector : connectors) {
            connector.start();
        }
    }

    @Override
    public void setServices(Service[] services) {
        this.services = services;
    }

    @Override
    public Service[] findServices() {
        return this.services;
    }

    @Override
    public void addConnector(Connector connector) {
        Connector[] result = new Connector[connectors.length + 1];
        System.arraycopy(connectors, 0, result, 0, connectors.length);
        result[connectors.length] = connector;
        connectors = result;
    }

    @Override
    public Executor getExecutor() {
        return this.executor;
    }
}
